package com.zijie.shopcategoryapi.category.service.impl;


import com.zijie.category.model.Category;
import com.zijie.category.service.CategoryService;
import com.zijie.shopcategoryapi.category.mapper.CategoryMapper;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@CacheConfig(cacheNames = "category")
@Service
public class CategoryServiceImpl implements CategoryService {


    private CategoryMapper categoryMapper;

    @Autowired
    public void setCategoryMapper(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Override
    public List<Category> findAll(Category category) {
        return categoryMapper.findAll(category);
    }

    @Cacheable(key = "'all'")
    @Override
    public List<Category> findAll() {
        return categoryMapper.selectList(null);
    }

    //生成树形结构
    @Cacheable(key = "'tree'")
    @Override
    public List<Category> findTree() {
        //代理调用可以出发缓存
        List<Category> categories=proxy().findAll();
        return mkTree(categories);
    }


    //树形结构
    @Cacheable(value = "category", key = "#id", unless = "#result == null")
    @Override
    public Category findById(Integer id) {
        List<Category> tree = proxy().findTree();
        return findById(tree,id);
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean add(Category category) {
        return categoryMapper.insert(category) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean update(Category category) {
        return categoryMapper.updateById(category) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int deleteById(Integer id) {
        //树形结构 通过id进行返回
        Category category=proxy().findById(id);
        if (category.getChildren()!=null){
            throw new UnsupportedOperationException("请先删除子级分类");
        }
        //没有子节点就直接删除

        return categoryMapper.deleteById(id);
    }
    //生成树形结构
    private List<Category> mkTree(List<Category> categories) {
        Map<Integer, Category> cache=new HashMap<>();
        for (Category category : categories) {
            cache.put(category.getId(),category);
        }
        List<Category> roots=new ArrayList<>();
        //遍历缓存中的 value  全部的分类
        for (Category category : cache.values()) {
            if (category.getParentId()==null){
                roots.add(category);
            }else {
                Category parent=cache.get(category.getParentId());
                if (parent==null){
                    throw new RuntimeException("父级分类不存在");
                }
                //设置关联
                category.setParent( parent);
                if (parent.getChildren()==null){
                    parent.setChildren(new ArrayList<>());
                }
                //添加子级
                parent.getChildren().add(category);
            }
        }
        return roots;
    }


    //在一个分类集合中找制定编号的fenlei 深度
    private Category findById(List<Category> categories,Integer id) {
        for (Category category : categories){
            if (category.getId().equals(id)){
                return category;
            }
            if (category.getChildren()!=null){
                Category found = findById(category.getChildren(), id);
                if (found!=null){
                    return found;
                }
            }
        }
        return null;
    }

    //当前类的代理
    private CategoryService proxy(){
        return (CategoryService) AopContext.currentProxy();
    }

}
